﻿// -----------------------------------------------------------------------
// <copyright file="ViewDataService.cs" company="AGR">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace AGR.Services.FormInformation
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using AGR.Model;
    using AGR.Data.Repository;
    using AGR.Data.Repository.Contract;
    using System.Linq.Expressions;
    using AGR.Services.Audit;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class FormInformationService : IFormInformationService
    {
        private IAuditLogService _auditLogService;

        public FormInformationService()
        {
            _auditLogService = new AuditLogService();
        }

        #region Private Methods

        private static void ActionResultError(ActionResult actionResult, Exception ex)
        {
            actionResult.Exception = ex;
            actionResult.IsSystemFailure = true;
            actionResult.Success = false;
        }

        #endregion

        #region Public Methods

        #region Countries

        public IList<Country> GetCountries()
        {
            using (IRepository<Country> repository = new CountryRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Country GetCountry(Expression<Func<Country, bool>> predicate)
        {
            using (IRepository<Country> repository = new CountryRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddCountry(Country entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Country> repository = new CountryRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.CountryName + ".";

                    _auditLogService.LogAudit("Country", "-", "Insert", "-", entity.CountryName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.CountryName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateCountry(Country entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Country> repository = new CountryRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.CountryName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.CountryName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteCountry(Country entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Country> repository = new CountryRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.CountryName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.CountryName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteCountry(string countryName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Country> repository = new CountryRepository())
                {
                    repository.DeleteBy(x => x.CountryName == countryName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + countryName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + countryName + ".";
            }

            return actionResult;
        }

        #endregion

        #region Equities

        public IList<Equity> GetEquitys()
        {
            using (IRepository<Equity> repository = new EquityRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Equity GetEquity(Expression<Func<Equity, bool>> predicate)
        {
            using (IRepository<Equity> repository = new EquityRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddEquity(Equity entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Equity> repository = new EquityRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.EquityName + ".";
                    _auditLogService.LogAudit("Equity", "-", "Insert", "-", entity.EquityName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.EquityName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateEquity(Equity entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Equity> repository = new EquityRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.EquityName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.EquityName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteEquity(Equity entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Equity> repository = new EquityRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.EquityName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.EquityName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteEquity(string equityName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Equity> repository = new EquityRepository())
                {
                    repository.DeleteBy(x => x.EquityName == equityName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + equityName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + equityName + ".";
            }

            return actionResult;
        }

        #endregion

        #region Languages

        public IList<Language> GetLanguages()
        {
            using (IRepository<Language> repository = new LanguageRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Language GetLanguage(Expression<Func<Language, bool>> predicate)
        {
            using (IRepository<Language> repository = new LanguageRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddLanguage(Language entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Language> repository = new LanguageRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.LanguageName + ".";

                    _auditLogService.LogAudit("Language", "-", "Insert", "-", entity.LanguageName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.LanguageName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateLanguage(Language entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Language> repository = new LanguageRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.LanguageName + ".";
                    _auditLogService.LogAudit("Language", "Displayed", "Update", "-", entity.Displayed.ToString(), entity.UserModified);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.LanguageName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteLanguage(Language entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Language> repository = new LanguageRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.LanguageName + ".";

                    _auditLogService.LogAudit("Language", "-", "Delete", entity.LanguageName, "-", entity.UserModified);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.LanguageName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteLanguage(string languageName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Language> repository = new LanguageRepository())
                {
                    repository.DeleteBy(x => x.LanguageName == languageName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + languageName + ".";

                    _auditLogService.LogAudit("Language", "-", "Delete", languageName, "-", user);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + languageName + ".";
            }

            return actionResult;
        }

        #endregion

        #region Months

        public IList<Month> GetMonths()
        {
            using (IRepository<Month> repository = new MonthRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Month GetMonth(Expression<Func<Month, bool>> predicate)
        {
            using (IRepository<Month> repository = new MonthRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddMonth(Month entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Month> repository = new MonthRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.MonthName + ".";
                    _auditLogService.LogAudit("Month", "-", "Insert", "-", entity.MonthName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.MonthName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateMonth(Month entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Month> repository = new MonthRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.MonthName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.MonthName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteMonth(Month entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Month> repository = new MonthRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.MonthName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.MonthName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteMonth(string monthName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Month> repository = new MonthRepository())
                {
                    repository.DeleteBy(x => x.MonthName == monthName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + monthName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + monthName + ".";
            }

            return actionResult;
        }

        #endregion

        #region Provinces

        public IList<Province> GetProvinces()
        {
            using (IRepository<Province> repository = new ProvinceRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Province GetProvince(Expression<Func<Province, bool>> predicate)
        {
            using (IRepository<Province> repository = new ProvinceRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddProvince(Province entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Province> repository = new ProvinceRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.ProvinceName + ".";
                    _auditLogService.LogAudit("Province", "-", "Insert", "-", entity.ProvinceName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.ProvinceName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateProvince(Province entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Province> repository = new ProvinceRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.ProvinceName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.ProvinceName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteProvince(Province entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Province> repository = new ProvinceRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.ProvinceName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.ProvinceName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteProvince(string provinceName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Province> repository = new ProvinceRepository())
                {
                    repository.DeleteBy(x => x.ProvinceName == provinceName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + provinceName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + provinceName + ".";
            }

            return actionResult;
        }

        #endregion

        #region ResedentialStatus

        public IList<ResedentialStatus> GetResedentialStatus()
        {
            using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
            {
                return repository.GetAll().ToList();
            }
        }

        public ResedentialStatus GetResedentialStatus(Expression<Func<ResedentialStatus, bool>> predicate)
        {
            using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddResedentialStatus(ResedentialStatus entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.ResedentialStatusName + ".";
                    _auditLogService.LogAudit("ResedentialStatus", "-", "Insert", "-", entity.ResedentialStatusName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.ResedentialStatusName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateResedentialStatus(ResedentialStatus entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.ResedentialStatusName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.ResedentialStatusName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteResedentialStatus(ResedentialStatus entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.ResedentialStatusName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.ResedentialStatusName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteResedentialStatus(string resedentialStatusName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<ResedentialStatus> repository = new ResedentialStatusRepository())
                {
                    repository.DeleteBy(x => x.ResedentialStatusName == resedentialStatusName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + resedentialStatusName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + resedentialStatusName + ".";
            }

            return actionResult;
        }

        #endregion

        #region Weekdays

        public IList<Weekday> GetWeekdays()
        {
            using (IRepository<Weekday> repository = new WeekdayRepository())
            {
                return repository.GetAllReadOnly();
            }
        }

        public Weekday GetWeekday(Expression<Func<Weekday, bool>> predicate)
        {
            using (IRepository<Weekday> repository = new WeekdayRepository())
            {
                return repository.FindBy(predicate).Single();
            }
        }

        public ActionResult AddWeekday(Weekday entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Weekday> repository = new WeekdayRepository())
                {
                    repository.Add(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordInserted + " Record: " + entity.WeekDayName + ".";
                    _auditLogService.LogAudit("Weekday", "-", "Insert", "-", entity.WeekDayName, entity.UserCreated);
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericAddErrorMessage + " Record: " + entity.WeekDayName + ".";
            }

            return actionResult;
        }

        public ActionResult UpdateWeekday(Weekday entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Weekday> repository = new WeekdayRepository())
                {
                    repository.Update(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordUpdated + " Record: " + entity.WeekDayName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericUpdateErrorMessage + " Record: " + entity.WeekDayName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteWeekday(Weekday entity)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Weekday> repository = new WeekdayRepository())
                {
                    repository.Delete(entity);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + entity.WeekDayName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + entity.WeekDayName + ".";
            }

            return actionResult;
        }

        public ActionResult DeleteWeekday(string weekdayName, string user)
        {
            ActionResult actionResult = new ActionResult();

            try
            {
                using (IRepository<Weekday> repository = new WeekdayRepository())
                {
                    repository.DeleteBy(x => x.WeekDayName == weekdayName);
                    repository.SaveChanges();

                    actionResult.Success = true;
                    actionResult.Message = actionResult.RecordDeleted + " Record: " + weekdayName + ".";
                }
            }
            catch (Exception ex)
            {
                ActionResultError(actionResult, ex);
                actionResult.Message = actionResult.GenericDeleteErrorMessage + " Record: " + weekdayName + ".";
            }

            return actionResult;
        }

        #endregion

        #endregion

        #region Dispose

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {

                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion
    }
}
